package com.maimang.platform.dsp.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.maimang.platform.common.entity.SysDictData;
import com.maimang.platform.common.utils.DateUtils;
import com.maimang.platform.dsp.constant.AdApi;
import com.maimang.platform.dsp.constant.AdvertiserApi;
import com.maimang.platform.dsp.constant.AppInfo;
import com.maimang.platform.dsp.constant.ParamFields;
import com.maimang.platform.dsp.entity.Advertiser;
import com.maimang.platform.dsp.entity.AdvertiserIds;
import com.maimang.platform.dsp.entity.AdvertiserShort;
import com.maimang.platform.dsp.enums.AdvertiserRole;
import com.maimang.platform.dsp.mapper.AdvertiserIdsMapper;
import com.maimang.platform.dsp.mapper.AdvertiserMapper;
import com.maimang.platform.dsp.service.AccessTokenService;
import com.maimang.platform.dsp.service.AdvertiserService;
import com.maimang.platform.dsp.utils.ApiService;
import com.maimang.platform.lang.ConvertUtils;
import com.maimang.platform.lang.StringUtils;
import com.maimang.platform.service.DictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;

/**
 * @author Rocky
 * @version 1.0.0
 * @classname AdvertiserServiceImpl
 * @description <br>广告主 服务层实现</br>
 * @date 2019-07-31 10:07:36
 * @email jintaozhao@qq.com
 */
@Service
public class AdvertiserServiceImpl implements AdvertiserService {

	@Autowired
	private AdvertiserMapper advertiserMapper;

	@Autowired
	private AdvertiserIdsMapper advertiserIdsMapper;

	@Autowired
	private ApiService apiService;

	@Autowired
	private DictService dictService;

	@Autowired
	private AccessTokenService accessTokenService;

	/**
	 * 查询广告主信息
	 *
	 * @param id 广告主ID
	 * @return 广告主信息
	 */
	@Override
	public Advertiser selectAdvertiserById(Long id) {
		if (id == null)
			return null;
		Advertiser advertiser = advertiserMapper.selectAdvertiserById(id);
		return advertiser;
	}

	/**
	 * 查询广告主信息（简约版）
	 *
	 * @param id 广告主id
	 * @return 广告主信息
	 */
	@Override
	public AdvertiserShort selectShortById(Long id) {
		return advertiserMapper.selectShortById(id);
	}

	/**
	 * 查询广告主列表
	 *
	 * @param advertiser 广告主信息
	 * @return 广告主集合
	 */
	@Override
	public List<Advertiser> selectAdvertiserList(Advertiser advertiser) {
		return advertiserMapper.selectAdvertiserList(advertiser);
	}

	/**
	 * 查询广告主列表
	 *
	 * @param advertiser 广告主信息
	 * @return 广告主集合
	 */
	@Override
	public List<AdvertiserShort> selectShortList(Advertiser advertiser) {
		return advertiserMapper.selectShortList(advertiser);
	}


	/**
	 * 查询符合条件的数量
	 *
	 * @param advertiser 查询条件
	 * @return
	 */
	@Override
	public int selectCount(Advertiser advertiser) {
		return advertiserMapper.selectCount(advertiser);
	}

	/**
	 * 新增广告主
	 *
	 * @param advertiser 广告主信息
	 * @return 结果
	 */
	@Transactional
	@Override
	public int insertAdvertiser(Advertiser advertiser) {
		if (StringUtils.isNull(advertiser))
			return 0;

		if (StringUtils.isEmpty(advertiser.getPassword())) {
			advertiser.setPassword(AppInfo.DEFAULT_PASSWORD);
		}
		JSONObject result = this.createAdvertiser(advertiser);
		if (result.getInteger("code") == 0) {
			JSONObject data = result.getJSONObject("data");
			String advertiserId = data.getString("advertiser_id");
			advertiser.setId(Long.parseLong(advertiserId));
		} else {
			return 0;
		}

		return advertiserMapper.insertAdvertiser(advertiser);
	}

	/**
	 * 修改广告主
	 *
	 * @param advertiser 广告主信息
	 * @return 结果
	 */
	@Transactional
	@Override
	public int updateAdvertiser(Advertiser advertiser) {
		JSONObject result = this.modifyAdvertiser(advertiser);
		if (result != null) {
			if (result.getInteger("code") == 0) {
				JSONObject data = result.getJSONObject("data");
				int needAudit = data.getInteger("need_audit");
				if (needAudit == 1) {
					advertiser.setStatus("待审状态");
				} else if (needAudit == 0) {
					advertiser.setStatus(StringUtils.EMPTY);
				}
			} else {
				return 0;
			}
		}
		return advertiserMapper.updateAdvertiser(advertiser);
	}

	/**
	 * 删除广告主对象(本地删除，头条平台不删除，下次去查询最新数据)
	 *
	 * @param ids 需要删除的数据ID
	 * @return 结果
	 */
	@Transactional
	@Override
	public int deleteAdvertiserByIds(String ids) {
		return advertiserMapper.deleteAdvertiserByIds(ConvertUtils.toStrArray(ids));
	}

	/**
	 * 请求广告主api接口并处理返回结果集
	 *
	 * @param ids 广告主id列表
	 * @return 广告主详情信息列表
	 */
	@Override
	public void getAdvertiserDetails(long[] ids) {
		List<Advertiser> advertiserList = new ArrayList<>();
		Map params = new HashMap();
		params.put("advertiser_ids", ids);
		params.put("fields", ParamFields.ADVERTISER_INFO);
		String accessToken = getAccessToken();
		JSONObject result = apiService.sendGet(AdvertiserApi.INFO, accessToken, params);
		if (result.getIntValue("code") == 0) {
			JSONArray data = result.getJSONArray("data");
			advertiserList = data.toJavaList(Advertiser.class);

			for (int i = 0; i < advertiserList.size(); i++) {
				Advertiser advertiser = advertiserList.get(i);
				advertiser.setPassword(AppInfo.DEFAULT_PASSWORD);
				advertiser.setCreateUser(AppInfo.DEFAULT_USER);
				advertiser.setUpdateTime(DateUtils.getNowDate());
				advertiser.setUpdateUser(AppInfo.DEFAULT_USER);
				advertiserMapper.deleteAdvertiserById(advertiser.getId());
				advertiserMapper.insertAdvertiser(advertiser);

				AdvertiserIds advertiserIds = new AdvertiserIds();
				advertiserIds.setId(advertiser.getId());
				advertiserIds.setIsSync(1);
				advertiserIds.setUpdateTime(DateUtils.getNowDate());
				advertiserIdsMapper.updateAdvertiserIds(advertiserIds);
			}
		} else {
			if (result.getString("message").contains("Access token is invalid")) {
				accessTokenService.getRefreshToken();
				getAdvertiserDetails(ids);
			}
		}
	}

	private String getAccessToken() {
		return accessTokenService.getRefreshToken();
	}

	/**
	 * 获取账户授权下管理的广告主id列表
	 *
	 * @param advertiserId 广告主id、代理商id、或第三方id
	 */
	@Override
	public void getAdvertisers(String advertiserId) {
		String accessToken = this.getAccessToken();
		if (StringUtils.isEmpty(accessToken))
			return;

		AdvertiserIds base = new AdvertiserIds();
		base.setPId(Long.valueOf(advertiserId));
		List<AdvertiserIds> advertiserIdsList = advertiserIdsMapper.selectAdvertiserIdsList(base);

		double total = advertiserIdsList.size();
		int pageSize = 1000;
		int totalPage = (int) Math.ceil(total / pageSize);

		for (int i = 0; i < totalPage; i++) {
			int beginIndex = i * pageSize;
			int endIndex = (int) Math.min((i + 1) * pageSize, total);
			Executors.newFixedThreadPool(totalPage).execute(() -> {
				List<AdvertiserIds> advertiserIds = advertiserIdsList.subList(beginIndex, endIndex);
				int step = 20;
				long[] ids = new long[20];
				for (int j = 0; j < advertiserIds.size(); j += step) {
					for (int m = 0; m < step; m++) {
						ids[m] = advertiserIds.get(j + m).getId();
					}
					getAdvertiserDetails(ids);
					try {
						Thread.sleep(1500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			});
		}
	}

	/**
	 * 获取广告主代理商下属所有广告主id
	 *
	 * @return 广告主列表id
	 */
	@Override
	public void getAdvertiserIds() throws InterruptedException {
		String accessToken = this.getAccessToken();
		if (StringUtils.isEmpty(accessToken))
			return;

		// 先清空数据
		advertiserIdsMapper.cleanIds();

		List<SysDictData> agents = dictService.getType("dsp_agent_info");
		for (int i = 0; i < agents.size(); i++) {
			SysDictData dictData = agents.get(i);
			if (StringUtils.isNull(dictData))
				break;
			String advertiserId = dictData.getDictValue();
			// 查询数据参数
			int page = 1, pageSize = 1000, totalPage = 0;

			Map<String, Object> param = new HashMap<>();
			// 查询数据参数
			do {
				// 调用api接口
				param.put("advertiser_id", advertiserId);
				param.put("page", page);
				param.put("page_size", pageSize);
				JSONObject resultObject = apiService.sendGet(AdApi.ADVERTISER_LIST, accessToken, param);
				if (resultObject != null && resultObject.getInteger("code") == 0) {
					JSONObject data = resultObject.getJSONObject("data");
					JSONObject object = data.getJSONObject("page_info");
					totalPage = object.getInteger("total_page");
					page = object.getInteger("page");

					JSONArray idList = data.getJSONArray("list");
					List<AdvertiserIds> ids = new ArrayList<>();
					for (int j = 0; j < idList.size(); j++) {
						AdvertiserIds adId = new AdvertiserIds();
						adId.setId(idList.getLongValue(j));
						adId.setPId(Long.parseLong(advertiserId));
						ids.add(adId);
					}
					if (ids.size() > 0) {
						advertiserIdsMapper.batchAdvertiserIds(ids);
						page++;
					}
					Thread.sleep(1000);
				}
			} while (page <= totalPage);
			// 同步完广告主id后，根据广告主id列表进行信息同步
		}
	}

	/**
	 * 重试同步
	 * 针对未同步或同步失败的广告主id列表
	 */
	@Override
	public void retryAdvertisers() {
		List<Long> targetIds = advertiserMapper.selectUnsyncIds();
		if (targetIds.size() == 0)
			return;
		String accessToken = this.getAccessToken();
		if (StringUtils.isEmpty(accessToken))
			return;
		int step = 10;
		for (int j = 0; j < targetIds.size(); j += step) {
			int length = Math.min(step, targetIds.size());
			long[] ids = new long[length];
			for (int m = 0; m < length; m++) {
				ids[m] = targetIds.get(j + m);
			}
			getAdvertiserDetails(ids);
			try {
				Thread.sleep(1500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		targetIds = advertiserMapper.selectUnsyncIds();
		if (targetIds.size() > 0) {
			retryAdvertisers();
		}
	}

	/**
	 * 创建广告主
	 *
	 * @param advertiser 广告主对象信息
	 * @return
	 */
	@Override
	public JSONObject createAdvertiser(Advertiser advertiser) {
		if (advertiser == null) return null;
		String accessToken = this.getAccessToken();
		Map paramMap = new HashMap();
		paramMap.put("name", advertiser.getName());
		paramMap.put("company", advertiser.getCompany());
		paramMap.put("role", AdvertiserRole.ROLE_CHILD_ADVERTISER);
		paramMap.put("email", advertiser.getEmail());
		paramMap.put("password", advertiser.getPassword());
		paramMap.put("promotion_area", 0);
		paramMap.put("center_province", 0);
		paramMap.put("center_city", 0);
		paramMap.put("industry", advertiser.getFirstIndustryName());
		paramMap.put("contacter", advertiser.getContacter());
		paramMap.put("phonenumber", advertiser.getPhonenumber());
		paramMap.put("telephone", advertiser.getTelephone());
		paramMap.put("address", advertiser.getAddress());
		paramMap.put("description", advertiser.getDescription());
		paramMap.put("license_no", advertiser.getLicenseNo());
		paramMap.put("license_province", advertiser.getLicenseCity());
		paramMap.put("license_city", advertiser.getLicenseCity());
		paramMap.put("license_file_id", advertiser.getLicenseFileId());
		JSONObject result = apiService.sendPost(AdvertiserApi.AD_CREATE, accessToken, paramMap);
		return result;
	}

	/**
	 * 修改广告主
	 *
	 * @param advertiser 广告主对象信息
	 * @return
	 */
	@Override
	public JSONObject modifyAdvertiser(Advertiser advertiser) {
		if (advertiser == null) return null;
		String accessToken = AppInfo.ACCESS_TOKEN;
		Map paramMap = new HashMap();
		paramMap.put("advertiser_id", advertiser.getId());
		paramMap.put("name", advertiser.getName());
		paramMap.put("contacter", advertiser.getContacter());
		paramMap.put("phonenumber", advertiser.getPhonenumber());
		paramMap.put("telephone", advertiser.getTelephone());

		JSONObject result = apiService.sendPost(AdvertiserApi.AD_UPDATE, accessToken, paramMap);

		return result;
	}

}
